package network.editor;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.SwingUtilities;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import xujun.control.XContorlUtil;

import com.mxgraph.io.mxCodec;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxICell;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.view.mxGraph;

public class NetworkEditor extends BasicNetworkEditor {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

//	private static final Logger log = Logger.getLogger(NetworkEditor.class);

	public NetworkEditor() {
		this("MyVisio", new CustomGraphComponent(new CustomGraph()));
	}

	public NetworkEditor(String appTitle, mxGraphComponent component) {
		super(appTitle, component);
		graphComponent.getGraph();
	}

	public static class CustomGraphComponent extends mxGraphComponent {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public CustomGraphComponent(final mxGraph graph) {
			super(graph);
			setPageVisible(true);// 设置为页面模式
			setGridVisible(true);// 显示网格
			setToolTips(true);// 显示图元的tooltip
			setConnectable(false);// 图元本身不支持连接和自身复制连接，这样防止误操作

			getConnectionHandler().setCreateTarget(true);
			mxCodec codec = new mxCodec();
			Document doc = EditorResource.getDocument("default-style.xml");
			codec.decode(doc.getDocumentElement(), graph.getStylesheet());

			getViewport().setOpaque(false);
			setBackground(Color.WHITE);

			getGraphControl().addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent e) {
					// 鼠标双击
					if (e.getClickCount() == 2) {
						Object cell = getCellAt(e.getX(), e.getY());
						if (cell != null) {
							System.out.println("cell=" + graph.getLabel(cell));
						}
					}
				}
			});
		}

		public Object[] importCells(Object[] cells, double dx, double dy,
				Object target, Point location) {
			if (target == null && cells.length == 1 && location != null) {
				target = getCellAt(location.x, location.y);
				if (target instanceof mxICell && cells[0] instanceof mxICell) {
					mxICell targetCell = (mxICell) target;
					mxICell dropCell = (mxICell) cells[0];

					if (targetCell.isVertex() == dropCell.isVertex()
							|| targetCell.isEdge() == dropCell.isEdge()) {
						mxIGraphModel model = graph.getModel();
						model.setStyle(target, model.getStyle(cells[0]));
						graph.setSelectionCell(target);
						return null;
					}
				}
			}
			return super.importCells(cells, dx, dy, target, location);
		}
	}

	public static class CustomGraph extends mxGraph {
		protected Object edgeTemplate;

		public CustomGraph() {
			setAlternateEdgeStyle("edgeStyle=mxEdgeStyle.ElbowConnector;elbow=vertical");
		}

		public void setEdgeTemplate(Object template) {
			edgeTemplate = template;
		}

		// 通过自定义对象获得mxCell显示的text
		@Override
		public String convertValueToString(Object cell) {
			Element node = getCellBindObj(cell);
			if (node != null) {
				if (node.getTagName().equalsIgnoreCase("NetNode")) {
					return node.getAttribute("text");
				}
			}
			return super.convertValueToString(cell);
		}

		/*
		 * 当用户在画面上编辑mxCell的text之后，将该属性设置到NetNode上. cell是前一个绑定的对象
		 * newObject是当前的输入，就是一个String 最终将newObject绑定到新的Element，这样就实现了继续传递
		 */
		@Override
		public void cellLabelChanged(Object cell, Object newObject,
				boolean autoSize) {
			Element node = getCellBindObj(cell);
			if (node != null) {
				if (node.getTagName().equalsIgnoreCase("NetNode")) {
					String label = newObject.toString();
					node = (Element) node.cloneNode(true);
					node.setAttribute("text", label);
					newObject = node;
				}
			}
			super.cellLabelChanged(cell, newObject, autoSize);
		}

		@Override
		public String getToolTipForCell(Object cell) {
			Element node = getCellBindObj(cell);
			if (node != null) {
				if (node.getTagName().equalsIgnoreCase("NetNode")) {
					return String
							.format("<html>%s<br>代理引擎:%s</html>",
									node.getAttribute("text"),
									node.getAttribute("key"));
				}
			}
			return "";
		}

		/**
		 * 获得mxCell绑定的自定义对象
		 * @param cell
		 * @return
		 */
		private Element getCellBindObj(Object cell) {
			// 如果是mxcell对象
			if (cell instanceof mxCell) {
				// 获得mxcell对象绑定的数据对象
				Object bindObj = ((mxCell) cell).getValue();
				if (bindObj instanceof Element) {
					Element node = (Element) bindObj;
					return node;
				}
			}
			return null;
		}

		@Override
		public Object createEdge(Object parent, String id, Object value,
				Object source, Object target, String style) {
			if (edgeTemplate != null) {
				mxCell edge = (mxCell) cloneCells(new Object[] { edgeTemplate })[0];
				edge.setId(id);
				return edge;
			}
			return super.createEdge(parent, id, value, source, target, style);
		}
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				XContorlUtil.setupLookAndFeel();
				mxConstants.SHADOW_COLOR = Color.LIGHT_GRAY;
				NetworkEditor editor = new NetworkEditor();
				editor.createFrame(new EditorMenuBar(editor)).setVisible(true);
			}
		});
	}
}